#include "bctoolbox/vfs.h"
#include "belle-sip/utils.h"
#include "linphone/account_creator.h"
#include "linphone/api/c-account-params.h"
#include "linphone/api/c-account.h"
#include "linphone/api/c-address.h"
#include "linphone/api/c-auth-info.h"
#include "linphone/call.h"
#include "linphone/core.h"
#include "log/ohos_log.h"
#include "napi/native_api.h"

#include <iostream>
#include <linphone/core.h>
#include <thread>

// 注册状态变化回调函数
static void registration_state_changed(LinphoneCore *core, LinphoneAccount *account, LinphoneRegistrationState state,
                                       const char *message) {
    LOGE("messageCallBack Registration状态");
    switch (state) {
    case LinphoneRegistrationNone:
        LOGE("messageCallBack未初始化");
        break;
    case LinphoneRegistrationProgress:
        LOGE("messageCallBack正在注册...");
        break;
    case LinphoneRegistrationOk:
        LOGE("messageCallBack注册成功!");
        break;
    case LinphoneRegistrationCleared:
        LOGE("messageCallBack已注销");
        break;
    case LinphoneRegistrationFailed:
        LOGE("messageCallBack注册失败");
        break;
    default:
        LOGE("messageCallBack未知状态");
    }
}


int login() {
    std::thread t([]() {
        LinphoneCoreVTable vtable = {0};
        linphone_core_enable_logs(NULL);
        vtable.account_registration_state_changed = registration_state_changed;
        LinphoneCore *lc = linphone_core_new(&vtable, NULL, NULL, NULL);
         //这两个配置无效 目前在底层写死
//        LinphoneConfig *config = linphone_factory_create_config_with_factory(linphone_factory_get(), nullptr, NULL);
//        linphone_config_set_string(config, "lime", "x3dh_db_path", "/data/storage/el2/base/haps/entry/cache/x3dh.c25519.sqlite3");
//        linphone_config_set_string(config, "storage", "uri", "/data/storage/el2/base/haps/entry/cache/linphone.db");
        // 配置认证信息
        LinphoneAuthInfo *auth_info = linphone_auth_info_new("1006", nullptr, "1006", nullptr, nullptr, nullptr);
        linphone_core_add_auth_info(lc, auth_info);

        // 创建账户参数（添加错误检查）
        LinphoneAddress *identity_addr = linphone_address_new("sip:1006@47.96.177.62:5060");
        if (!identity_addr) {
            LOGE("无效的Identity地址!");
            return;
        }
        LinphoneAddress *server_addr = linphone_address_new("sip:47.96.177.62:5060;transport=udp");
        if (!server_addr) {
            LOGE("无效的服务器地址!");
            linphone_address_unref(identity_addr);
            return;
        }
        LinphoneAccountParams *account_params = linphone_account_params_new(nullptr, FALSE);
        linphone_account_params_set_identity_address(account_params, identity_addr);
        linphone_account_params_set_server_address(account_params, server_addr);
        linphone_account_params_enable_register(account_params, TRUE);

        LinphoneAccount *account = linphone_core_create_account(lc, account_params);
        if (!account) {
            LOGE("账户添加失败!");
        }

        int rv = linphone_core_add_account(lc, account);
        linphone_core_set_default_account(lc, account);
        LOGE("账户添加linphone_core_add_account %d", rv);


        // 释放临时对象
//        linphone_address_unref(identity_addr);
//        linphone_address_unref(server_addr);
//        linphone_account_params_unref(account_params);
        
        while (true) {
            linphone_core_iterate(lc);
            std::this_thread::sleep_for(std::chrono::milliseconds(100));
            // 根据注册状态提前退出
            LinphoneRegistrationState state = linphone_account_get_state(account);
            LOGE("获取状态linphone_account_get_state %d", state);
        }

        LinphoneProxyConfig *proxy_cfg;

        proxy_cfg = linphone_core_get_default_proxy_config(lc);  /* get default proxy config*/
        linphone_proxy_config_edit(proxy_cfg);                   /*start editing proxy configuration*/
        linphone_proxy_config_enable_register(proxy_cfg, FALSE); /*de-activate registration for this proxy config*/
        linphone_proxy_config_done(proxy_cfg);                   /*initiate REGISTER with expire = 0*/

        while (linphone_proxy_config_get_state(proxy_cfg) != LinphoneRegistrationCleared) {
            linphone_core_iterate(lc); /*to make sure we receive call backs before shutting down*/
            ms_usleep(50000);
        }


        // 清理资源
//        linphone_core_remove_account(lc, account);
//        linphone_account_unref(account);
//        linphone_core_unref(lc);
//        linphone_core_cbs_unref(cbs);
//        linphone_auth_info_unref(auth_info);
    });
    t.detach();
    return 0;
}


static napi_value LoginLinphone(napi_env env, napi_callback_info info) {
    login();
    return nullptr;
}

EXTERN_C_START
static napi_value Init(napi_env env, napi_value exports) {
    napi_property_descriptor desc[] = {{"loginLinphone", nullptr, LoginLinphone, nullptr, nullptr, nullptr, napi_default, nullptr}};
    napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
    return exports;
}
EXTERN_C_END

static napi_module demoModule = {
    .nm_version = 1,
    .nm_flags = 0,
    .nm_filename = nullptr,
    .nm_register_func = Init,
    .nm_modname = "entry",
    .nm_priv = ((void *)0),
    .reserved = {0},
};

extern "C" __attribute__((constructor)) void RegisterEntryModule(void) { napi_module_register(&demoModule); }
